home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Topik / Topik - Disk 16 - KnowAboutIt (19xx)(Topik Public Domain)(PD)[WB].zip / Topik - Disk 16 - KnowAboutIt (19xx)(Topik Public Domain)(PD)[WB].adf / MicroRayDbw / texture.c < prev    next >
C/C++ Source or Header  |  1988-12-11  |  6KB  |  221 lines

  1. /************************************************************************
  2.  *                                    *
  3.  *            Copyright (c) 1988, David B. Wecker            *
  4.  *                All Rights Reserved                *
  5.  *                                    *
  6.  * This file is part of DBW_uRAY                    *
  7.  *                                    *
  8.  * DBW_uRAY is distributed in the hope that it will be useful, but    *
  9.  * WITHOUT ANY WARRANTY. No author or distributor accepts        *
  10.  * responsibility to anyone for the consequences of using it or for    *
  11.  * whether it serves any particular purpose or works at all, unless    *
  12.  * he says so in writing. Refer to the DBW_uRAY General Public        *
  13.  * License for full details.                        *
  14.  *                                    *
  15.  * Everyone is granted permission to copy, modify and redistribute    *
  16.  * DBW_uRAY, but only under the conditions described in the        *
  17.  * DBW_uRAY General Public License. A copy of this license is        *
  18.  * supposed to have been given to you along with DBW_uRAY so you    *
  19.  * can know your rights and responsibilities. It should be in a file    *
  20.  * named COPYING. Among other things, the copyright notice and this    *
  21.  * notice must be preserved on all copies.                *
  22.  ************************************************************************
  23.  *                                    *
  24.  * Authors:                                *
  25.  *    DBW - David B. Wecker                        *
  26.  *                                    *
  27.  * Versions:                                *
  28.  *    V1.0 881023 DBW    - First released version            *
  29.  *    V1.1 881110 DBW - Fixed scan coherence code            *
  30.  *    V1.2 881125 DBW - Removed ALL scan coherence code (useless)    *
  31.  *              added "fat" extent boxes            *
  32.  *                                    *
  33.  ************************************************************************/
  34.  
  35. #include "uray.h"
  36.  
  37. /************************************************************************/
  38. /**************** This module computes textures of objects **************/
  39. /************************************************************************/
  40.  
  41. /* get the procedure texture */
  42. void gettex(n,intersect,normal,diffuse)
  43. NODE    *n;
  44. VEC    intersect,normal,diffuse;
  45.     {
  46.     int        i,j,k;
  47.     FLTDBL  d;
  48.  
  49.     /* start with the default diffuse color */
  50.     vcopy(n->att->color,diffuse);
  51.     switch (n->att->tex) {
  52.  
  53.     /* no texture */
  54.     case 0:
  55.     break;
  56.  
  57.     /* checker board, p1 = alternate color, p2 = scale */
  58.     case 1:
  59.     for (i=j=0; i<3; i++) {
  60.         if (n->att->p2[i] > 0.0) {
  61.         k = (int)(intersect[i] / n->att->p2[i]);
  62.         if (k < 0) j -= k;
  63.         else       j += k;
  64.         }
  65.         }
  66.     if (j & 1) { vcopy(n->att->p1,diffuse);  }
  67.     break;
  68.  
  69.     /* random mottled texture, p1 = alternate color */
  70.     case 2:
  71.     for (i=0; i<3; i++) {
  72.         diffuse[i] *= (d=rnd());
  73.         diffuse[i] += (1.0-d) * n->att->p1[i];
  74.         }
  75.     break;
  76.  
  77.     /* blend textures */
  78.     case 3:        /* X axis blend, p1 = alternate color, p2 = coordinate */
  79.     case 4:        /* Y axis blend, p1 = alternate color, p2 = coordinate */
  80.     case 5:        /* Z axis blend, p1 = alternate color, p2 = coordinate */
  81.     i = n->att->tex - 3;
  82.     if (intersect[i] > n->att->p2[1])   d = n->att->p2[2] - n->att->p2[1];
  83.     else                     d = n->att->p2[0] - n->att->p2[1];
  84.  
  85.     if (d == 0.0) break;
  86.     d = (intersect[i] - n->att->p2[1]) / d;
  87.     
  88.     if (d > 1.0) d = 1.0;
  89.     if (d < 0.0) d = 0.0;
  90.  
  91.     for (i=0; i<3; i++) {
  92.         diffuse[i]    *= d;
  93.         diffuse[i]    += (1.0-d) * n->att->p1[i];
  94.         }
  95.     break;
  96.     }
  97.     }
  98.  
  99. /* return background value (computes sky and ground colors) */
  100. void getamb(frm, dir, retval)
  101. VEC frm, dir, retval;
  102.     {
  103.     FLTDBL  v;
  104.     int        i;
  105.  
  106.     if (dir[1] < 0.0) {
  107.     vcopy(GROUND,retval);
  108.     return;
  109.     }
  110.     if (dir[2] < 0.0)    v = 0.0;
  111.     else {
  112.     v = (1.0 - dir[1]) * dir[2];
  113.     if (v > 1.0) v = 1.0;
  114.     else         v *= v;
  115.     }
  116.     for (i=0; i<3; i++) {
  117.     retval[i]  = NEAR[i] * (1.0 - v);
  118.     retval[i] +=  FAR[i] * v;
  119.     }    
  120.     }
  121.  
  122. /* figure out ripple for current point inside of a wave surface */
  123. void calcripple(point,w,ripple)
  124. VEC    point;
  125. int    w;
  126. VEC    ripple;
  127.     {
  128.     FLTDBL  riprad,damper,tmp;
  129.     int        i,iriprad;
  130.  
  131.     riprad = 0.0;
  132.     for (i=0; i<3; i++) {
  133.     ripple[i] = tmp = waves[w].cen[i] - point[i];
  134.     riprad     += tmp * tmp;
  135.     }
  136.     /* unit vector pointing away from wave center */
  137.     vunit(ripple,ripple);
  138.  
  139.     riprad  =  sqrt(riprad);        /* distance from center to point */
  140.     riprad +=  waves[w].phase * waves[w].length;  /* move it */
  141.  
  142.     riprad /= waves[w].length;  /* scale half-wave crest to 0..1 */
  143.     if (waves[w].damp == 1.0)    damper = 1.0;
  144.     else            damper = pow(waves[w].damp,riprad);
  145.  
  146.     iriprad = (int)riprad;
  147.     if (iriprad & 1)  {/* negate it */
  148.     vscale(-1.0,ripple,ripple);
  149.     }
  150.     riprad -= (FLTDBL) iriprad;            /* just get fraction 0..1 */
  151.     riprad -= 0.5;                /* scale to -0.5 .. +0.5 */
  152.     if (riprad < 0.0) riprad = -riprad;        /* absolute value */
  153.     riprad  = 0.5 - riprad;            /* invert */
  154.     riprad *= damper;
  155.     riprad *= waves[w].amp;
  156.     vscale(riprad,ripple,ripple);        /* scale bend */
  157.     }
  158.  
  159. /* find surface normal for any object */
  160. FLTDBL findnormal(s,dir,intersect,normal,eflip)
  161. NODE    *s;
  162. VEC    dir,intersect,normal;
  163. int    *eflip;
  164.     {
  165.     int        i;
  166.     FLTDBL  d;
  167.     VEC        ripple,fuzzy;
  168.  
  169.     /* first get the standard normal */
  170.     switch (s->typ) {
  171.     case TYP_S:      spherenormal(intersect,s,normal); break;
  172.     default:     planenormal(s,normal);
  173.     }
  174.  
  175.     /* do any desired waves */
  176.     if (s->att->wave != -1) { /* don't bother checking if there's no waves*/
  177.     if (s->att->wave == -2) { /* fiddle with normal for all ripples */
  178.         for (i = 0; i < nwaves; i++) {
  179.         calcripple(intersect,i,ripple);  /* calculate the wave perturbation */
  180.         vadd(ripple,normal,normal);  /* add ripple bend to normal */
  181.         }
  182.         }
  183.  
  184.     /* fiddle with normal for one ripple */
  185.         else if (s->att->wave >= 0) {
  186.         calcripple(intersect,s->att->wave,ripple);  /* calc wave perturbation */
  187.         vadd(ripple,normal,normal);  /* add ripple bend to normal */
  188.         }
  189.     vunit(normal,normal);  /* make sure it's a unit vector after all that */
  190.     }
  191.  
  192.     /* Add any general normal perturbations */
  193.     if (s->att->kf > 0.0) {
  194.  
  195.     /* Perturb the normal randomly to produce fuzzy surfaces */
  196.     fuzzy[0] = rnd();  /* 0..1 */
  197.     fuzzy[1] = rnd();
  198.     fuzzy[2] = rnd();
  199.     if (rnd() < 0.5) fuzzy[0] = -fuzzy[0];
  200.     if (rnd() < 0.5) fuzzy[1] = -fuzzy[1];
  201.     if (rnd() < 0.5) fuzzy[2] = -fuzzy[2];
  202.  
  203.     /* 'fuzzy' is now approximately a random unit vector */
  204.     vcomb(rnd() * s->att->kf,fuzzy,normal,normal);
  205.     vunit(normal,normal);  /* make sure it's a unit vector after all that */
  206.     }
  207.  
  208.     /* make sure the normal is on the correct side of the surface */
  209.     d        = -vdot(dir,normal);
  210.     *eflip  = 0;
  211.     if (d < 0.0) {
  212.     vscale(-1.0, normal, normal);
  213.     *eflip    = 1;
  214.     d    = -d;
  215.     }
  216.  
  217.     return d;
  218.     }
  219.  
  220.  
  221.